//
//  WebView.swift
//  SwiftUIBook
//
//  Created by True on 2023/8/3.
//

import SwiftUI
import WebKit

struct WebView {
    
    @Binding var urlStr: String
    
    public func onDidFinish(_ action: @escaping (_ urlString: String, _ html: String,_ nextAction: @escaping ()->Void) -> Void) -> WebView {
        delegate.onDidFinishAction = action
        return self
    }
    
    private let delegate = Coordinator()
    
    class Coordinator: NSObject, WKNavigationDelegate, WKUIDelegate {
        
        var curWebView: WebView?
        
        var lastUrl: String?
        
        var onDidFinishAction: ((String, String, @escaping ()->Void)->Void)?
        
        private func nextWebPage(_ webView: WKWebView) {
            guard webView.isLoading == false else {
                print("break: webView isLoading ------------- ")
                return
            }
            
            let js = """
                        var a = document.getElementById("pb_next");
                        if (a == null) {
                            a = document.getElementById("pt_next");
                        }
                        if (a == null) {
                            a = document.getElementById("next_url");
                        }
                        if (a == null) {
                            a = document.getElementById("next");
                        }
                        if (a == null) {
                            a = document.getElementsByClassName("jump-chapter-links")[1];
                        }
                        if (a == null) {
                            if (document.getElementsByClassName("bottem1")[0]) {
                                a = document.getElementsByClassName("bottem1")[0].children[2];
                            }
                        }
                        if (a == null) {
                            if (document.getElementsByClassName("pereview")[0]) {
                                a = document.getElementsByClassName("pereview")[0].children[2];
                                if (a == null) {
                                    a = document.getElementsByClassName("pereview")[0].children[1];
                                }
                            }
                        }
                        if (a != null) {
                            a.click();
                        }
                """
            webView.evaluateJavaScript(js, completionHandler: nil)
        }
        
        //MARK: - WKNavigationDelegate
        func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
            print("\(#function)")
            print("\(String(describing: navigationAction.request.url?.absoluteString))")
            
            decisionHandler(.allow)
        }
        
        func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
            print("\(#function)")
            print("load url -- \(String(describing: webView.url))")
        }
        
        func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
            print("error -- \(error)")
        }
        
        func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
            print("\(#function)")
            if let curUrlStr = webView.url?.absoluteString {
                lastUrl = curUrlStr
                curWebView?.urlStr = curUrlStr
            }
            //TODO: 在这获取网页数据
            if let action = onDidFinishAction {
                let getHtml_js = "document.documentElement.innerHTML"
                webView.evaluateJavaScript(getHtml_js) { [weak self] (html, error) in
                    if let html = html as? String, let curUrlStr = webView.url?.absoluteString {
                        action(curUrlStr, html) {
                            self?.nextWebPage(webView)
                        }
                    }
                }
            }
        }
        
        //MARK: - WKUIDelegate
        func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
            print("\(#function)")
            if navigationAction.targetFrame == nil || !navigationAction.targetFrame!.isMainFrame {
                webView.load(navigationAction.request)
            }
            return nil
        }
    }
}


#if os(iOS)
extension WebView: UIViewRepresentable  {
    func makeUIView(context: Context) -> WKWebView {
        print("WebView UIViewRepresentable \(#function)")
        let view = WKWebView()
        view.navigationDelegate = context.coordinator
        view.uiDelegate = context.coordinator
        return view
    }
    
    func updateUIView(_ webView: WKWebView, context: Context) {
        print("WebView UIViewRepresentable \(#function) ----- \(String(describing: urlStr))")
        if urlStr != context.coordinator.lastUrl, let url = URL(string: urlStr) {
            let request = URLRequest(url: url)
            print("load request ----- \(String(describing: request.url?.absoluteString))")
            context.coordinator.lastUrl = urlStr
            webView.load(request)
        }
    }
    
    func makeCoordinator() -> Coordinator {
        print("WebView UIViewRepresentable \(#function)")
        delegate.curWebView = self
        return delegate
    }
}
#endif

#if os(macOS)
extension WebView: NSViewRepresentable  {
    func makeNSView(context: Context) -> WKWebView {
        print("WebView NSViewRepresentable \(#function)")
        let view = WKWebView()
        view.navigationDelegate = context.coordinator
        view.uiDelegate = context.coordinator
        return view
    }
    
    func updateNSView(_ webView: WKWebView, context: Context) {
        print("WebView NSViewRepresentable \(#function) ----- \(String(describing: urlStr))")
        if urlStr != context.coordinator.lastUrl, let url = URL(string: urlStr) {
            let request = URLRequest(url: url)
            print("load request ----- \(String(describing: request.url?.absoluteString))")
            context.coordinator.lastUrl = urlStr
            webView.load(request)
        }
    }
    
    func makeCoordinator() -> Coordinator {
        print("WebView NSViewRepresentable \(#function)")
        delegate.curWebView = self
        return delegate
    }
}
#endif




